home *** CD-ROM | disk | FTP | other *** search
/ The Complete Utilities To…ka 501 Killer Utilities! / 501 Killer Utilities! (Macworld July 1995).cdr / Programming / OutOfPhase1.1 Source / OutOfPhase Folder / FilterArray.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-03  |  28.2 KB  |  852 lines  |  [TEXT/KAHL]

  1. /* FilterArray.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "FilterArray.h"
  31. #include "Memory.h"
  32. #include "FilterSpec.h"
  33. #include "FilterFirstOrderLowpass.h"
  34. #include "FilterFirstOrderHighpass.h"
  35. #include "FilterSecondOrderReson.h"
  36. #include "FilterSecondOrderZero.h"
  37. #include "FilterButterworthLowpass.h"
  38. #include "FilterButterworthHighpass.h"
  39. #include "FilterButterworthBandpass.h"
  40. #include "FilterButterworthBandreject.h"
  41. #include "FilterNull.h"
  42.  
  43.  
  44. typedef struct FilterRec
  45.     {
  46.         struct FilterRec*        Next;
  47.         union
  48.             {
  49.                 FirstOrderLowpassRec*            FirstOrderLowpass;
  50.                 FirstOrderHighpassRec*        FirstOrderHighpass;
  51.                 SecondOrderResonRec*            SecondOrderReson;
  52.                 SecondOrderZeroRec*                SecondOrderZero;
  53.                 ButterworthLowpassRec*        ButterworthLowpass;
  54.                 ButterworthHighpassRec*        ButterworthHighpass;
  55.                 ButterworthBandpassRec*        ButterworthBandpass;
  56.                 ButterworthBandrejectRec*    ButterworthBandreject;
  57.                 FilterNullRec*                        NullFilter;
  58.                 void*                                            GenericRef;
  59.             } Left;
  60.         union
  61.             {
  62.                 FirstOrderLowpassRec*            FirstOrderLowpass;
  63.                 FirstOrderHighpassRec*        FirstOrderHighpass;
  64.                 SecondOrderResonRec*            SecondOrderReson;
  65.                 SecondOrderZeroRec*                SecondOrderZero;
  66.                 ButterworthLowpassRec*        ButterworthLowpass;
  67.                 ButterworthHighpassRec*        ButterworthHighpass;
  68.                 ButterworthBandpassRec*        ButterworthBandpass;
  69.                 ButterworthBandrejectRec*    ButterworthBandreject;
  70.                 FilterNullRec*                        NullFilter;
  71.                 void*                                            GenericRef;
  72.             } Right;
  73.         float                                (*ApplyFilter)(void* Ref, float Xin);
  74.         float                                CurrentMultiplier;
  75.         FilterTypes                    FilterType;
  76.         FilterScalings            FilterScaling;
  77.         float                                Cutoff;
  78.         float                                CutoffAccent1;
  79.         float                                CutoffAccent2;
  80.         float                                CutoffAccent3;
  81.         float                                CutoffAccent4;
  82.         float                                Bandwidth;
  83.         float                                BandwidthAccent1;
  84.         float                                BandwidthAccent2;
  85.         float                                BandwidthAccent3;
  86.         float                                BandwidthAccent4;
  87.         float                                OutputMultiplier;
  88.         float                                OutputMultiplierAccent1;
  89.         float                                OutputMultiplierAccent2;
  90.         float                                OutputMultiplierAccent3;
  91.         float                                OutputMultiplierAccent4;
  92.     } FilterRec;
  93.  
  94.  
  95. struct FilterArrayRec
  96.     {
  97.         /* list of filters to process */
  98.         FilterRec*                    Filters;
  99.  
  100.         /* stuff */
  101.         long                                SamplingRate;
  102.         MyBoolean                        StereoFlag;
  103.  
  104.         /* garbage link */
  105.         FilterArrayRec*            Next;
  106.     };
  107.  
  108.  
  109. static FilterArrayRec*                FilterArrayFreeList = NIL;
  110. static FilterRec*                            FilterFreeList = NIL;
  111.  
  112.  
  113. /* flush cached filter array records */
  114. void                            FlushCachedFilterArrayStuff(void)
  115.     {
  116.         while (FilterArrayFreeList != NIL)
  117.             {
  118.                 FilterArrayRec*        Temp;
  119.  
  120.                 Temp = FilterArrayFreeList;
  121.                 FilterArrayFreeList = FilterArrayFreeList->Next;
  122.                 ReleasePtr((char*)Temp);
  123.             }
  124.         while (FilterFreeList != NIL)
  125.             {
  126.                 FilterRec*                Temp;
  127.  
  128.                 Temp = FilterFreeList;
  129.                 FilterFreeList = FilterFreeList->Next;
  130.                 ReleasePtr((char*)Temp);
  131.             }
  132.     }
  133.  
  134.  
  135. /* create a new parallel filter processor */
  136. FilterArrayRec*        NewFilterArrayProcessor(struct FilterSpecRec* Template,
  137.                                         long FramesPerSecond, MyBoolean StereoFlag)
  138.     {
  139.         FilterArrayRec*    Array;
  140.         long                        Scan;
  141.         long                        Limit;
  142.  
  143.         CheckPtrExistence(Template);
  144.         if (FilterArrayFreeList != NIL)
  145.             {
  146.                 Array = FilterArrayFreeList;
  147.                 FilterArrayFreeList = FilterArrayFreeList->Next;
  148.             }
  149.          else
  150.             {
  151.                 Array = (FilterArrayRec*)AllocPtrCanFail(sizeof(FilterArrayRec),"FilterArrayRec");
  152.                 if (Array == NIL)
  153.                     {
  154.                      FailurePoint1:
  155.                         return NIL;
  156.                     }
  157.             }
  158.         Array->SamplingRate = FramesPerSecond;
  159.         Array->StereoFlag = StereoFlag;
  160.         Array->Filters = NIL;
  161.         Limit = GetNumFiltersInSpec(Template);
  162.         for (Scan = 0; Scan < Limit; Scan += 1)
  163.             {
  164.                 FilterRec*            Filter;
  165.                 MyBoolean                LeftChannel;
  166.                 MyBoolean                RightChannel;
  167.  
  168.                 if (FilterFreeList != NIL)
  169.                     {
  170.                         Filter = FilterFreeList;
  171.                         FilterFreeList = FilterFreeList->Next;
  172.                     }
  173.                  else
  174.                     {
  175.                         Filter = (FilterRec*)AllocPtrCanFail(sizeof(FilterRec),"FilterRec");
  176.                         if (Filter == NIL)
  177.                             {
  178.                              FailurePoint2:
  179.                                 while (Array->Filters != NIL)
  180.                                     {
  181.                                         Filter = Array->Filters;
  182.                                         Array->Filters = Array->Filters->Next;
  183.                                         switch (Filter->FilterType)
  184.                                             {
  185.                                                 default:
  186.                                                     EXECUTE(PRERR(ForceAbort,"NewFilterArrayProcessor:  bad filter type"));
  187.                                                     break;
  188.                                                 case eFilterFirstOrderLowpass:
  189.                                                     if (Filter->Left.FirstOrderLowpass != NIL)
  190.                                                         {
  191.                                                             DisposeFirstOrderLowpass(Filter->Left.FirstOrderLowpass);
  192.                                                         }
  193.                                                     if (Filter->Right.FirstOrderLowpass != NIL)
  194.                                                         {
  195.                                                             DisposeFirstOrderLowpass(Filter->Right.FirstOrderLowpass);
  196.                                                         }
  197.                                                     break;
  198.                                                 case eFilterFirstOrderHighpass:
  199.                                                     if (Filter->Left.FirstOrderHighpass != NIL)
  200.                                                         {
  201.                                                             DisposeFirstOrderHighpass(Filter->Left.FirstOrderHighpass);
  202.                                                         }
  203.                                                     if (Filter->Right.FirstOrderHighpass != NIL)
  204.                                                         {
  205.                                                             DisposeFirstOrderHighpass(Filter->Right.FirstOrderHighpass);
  206.                                                         }
  207.                                                     break;
  208.                                                 case eFilterSecondOrderResonant:
  209.                                                     if (Filter->Left.SecondOrderReson != NIL)
  210.                                                         {
  211.                                                             DisposeSecondOrderReson(Filter->Left.SecondOrderReson);
  212.                                                         }
  213.                                                     if (Filter->Right.SecondOrderReson != NIL)
  214.                                                         {
  215.                                                             DisposeSecondOrderReson(Filter->Right.SecondOrderReson);
  216.                                                         }
  217.                                                     break;
  218.                                                 case eFilterSecondOrderZero:
  219.                                                     if (Filter->Left.SecondOrderZero != NIL)
  220.                                                         {
  221.                                                             DisposeSecondOrderZero(Filter->Left.SecondOrderZero);
  222.                                                         }
  223.                                                     if (Filter->Right.SecondOrderZero != NIL)
  224.                                                         {
  225.                                                             DisposeSecondOrderZero(Filter->Right.SecondOrderZero);
  226.                                                         }
  227.                                                     break;
  228.                                                 case eFilterButterworthLowpass:
  229.                                                     if (Filter->Left.ButterworthLowpass != NIL)
  230.                                                         {
  231.                                                             DisposeButterworthLowpass(Filter->Left.ButterworthLowpass);
  232.                                                         }
  233.                                                     if (Filter->Right.ButterworthLowpass != NIL)
  234.                                                         {
  235.                                                             DisposeButterworthLowpass(Filter->Right.ButterworthLowpass);
  236.                                                         }
  237.                                                     break;
  238.                                                 case eFilterButterworthHighpass:
  239.                                                     if (Filter->Left.ButterworthHighpass != NIL)
  240.                                                         {
  241.                                                             DisposeButterworthHighpass(Filter->Left.ButterworthHighpass);
  242.                                                         }
  243.                                                     if (Filter->Right.ButterworthHighpass != NIL)
  244.                                                         {
  245.                                                             DisposeButterworthHighpass(Filter->Right.ButterworthHighpass);
  246.                                                         }
  247.                                                     break;
  248.                                                 case eFilterButterworthBandpass:
  249.                                                     if (Filter->Left.ButterworthBandpass != NIL)
  250.                                                         {
  251.                                                             DisposeButterworthBandpass(Filter->Left.ButterworthBandpass);
  252.                                                         }
  253.                                                     if (Filter->Right.ButterworthBandpass != NIL)
  254.                                                         {
  255.                                                             DisposeButterworthBandpass(Filter->Right.ButterworthBandpass);
  256.                                                         }
  257.                                                     break;
  258.                                                 case eFilterButterworthBandreject:
  259.                                                     if (Filter->Left.ButterworthBandreject != NIL)
  260.                                                         {
  261.                                                             DisposeButterworthBandreject(Filter->Left.ButterworthBandreject);
  262.                                                         }
  263.                                                     if (Filter->Right.ButterworthBandreject != NIL)
  264.                                                         {
  265.                                                             DisposeButterworthBandreject(Filter->Right.ButterworthBandreject);
  266.                                                         }
  267.                                                     break;
  268.                                                 case eFilterNull:
  269.                                                     if (Filter->Left.NullFilter != NIL)
  270.                                                         {
  271.                                                             DisposeFilterNull(Filter->Left.NullFilter);
  272.                                                         }
  273.                                                     if (Filter->Right.NullFilter != NIL)
  274.                                                         {
  275.                                                             DisposeFilterNull(Filter->Right.NullFilter);
  276.                                                         }
  277.                                                     break;
  278.                                             }
  279.                                         ReleasePtr((char*)Filter);
  280.                                     }
  281.                                 ReleasePtr((char*)Array);
  282.                                 goto FailurePoint1;
  283.                             }
  284.                     }
  285.                 Filter->Next = Array->Filters;
  286.                 Array->Filters = Filter;
  287.                 Filter->FilterType = GetFilterType(Template,Scan);
  288.                 Filter->FilterScaling = GetFilterScalingMode(Template,Scan);
  289.                 Filter->Cutoff = GetFilterCutoff(Template,Scan);
  290.                 Filter->CutoffAccent1 = GetFilterCutoffAccent1(Template,Scan);
  291.                 Filter->CutoffAccent2 = GetFilterCutoffAccent2(Template,Scan);
  292.                 Filter->CutoffAccent3 = GetFilterCutoffAccent3(Template,Scan);
  293.                 Filter->CutoffAccent4 = GetFilterCutoffAccent4(Template,Scan);
  294.                 Filter->Bandwidth = GetFilterBandwidth(Template,Scan);
  295.                 Filter->BandwidthAccent1 = GetFilterBandwidthAccent1(Template,Scan);
  296.                 Filter->BandwidthAccent2 = GetFilterBandwidthAccent2(Template,Scan);
  297.                 Filter->BandwidthAccent3 = GetFilterBandwidthAccent3(Template,Scan);
  298.                 Filter->BandwidthAccent4 = GetFilterBandwidthAccent4(Template,Scan);
  299.                 Filter->OutputMultiplier = GetFilterOutputMultiplier(Template,Scan);
  300.                 Filter->OutputMultiplierAccent1 = GetFilterOutputMultiplierAccent1(Template,Scan);
  301.                 Filter->OutputMultiplierAccent2 = GetFilterOutputMultiplierAccent2(Template,Scan);
  302.                 Filter->OutputMultiplierAccent3 = GetFilterOutputMultiplierAccent3(Template,Scan);
  303.                 Filter->OutputMultiplierAccent4 = GetFilterOutputMultiplierAccent4(Template,Scan);
  304.                 Filter->Left.GenericRef = NIL;
  305.                 Filter->Right.GenericRef = NIL;
  306.                 switch (GetFilterChannel(Template,Scan))
  307.                     {
  308.                         default:
  309.                             EXECUTE(PRERR(ForceAbort,"NewFilterArrayProcessor:  bad channel type"));
  310.                             break;
  311.                         case eFilterLeft:
  312.                             LeftChannel = True;
  313.                             RightChannel = False;
  314.                             break;
  315.                         case eFilterRight:
  316.                             LeftChannel = False;
  317.                             RightChannel = True;
  318.                             break;
  319.                         case eFilterBoth:
  320.                             LeftChannel = True;
  321.                             RightChannel = True;
  322.                             break;
  323.                     }
  324.                 switch (Filter->FilterType)
  325.                     {
  326.                         default:
  327.                             EXECUTE(PRERR(ForceAbort,"NewFilterArrayProcessor:  bad filter type"));
  328.                             break;
  329.                         case eFilterFirstOrderLowpass:
  330.                             if (LeftChannel)
  331.                                 {
  332.                                     Filter->Left.FirstOrderLowpass = NewFirstOrderLowpass();
  333.                                     if (Filter->Left.FirstOrderLowpass == NIL)
  334.                                         {
  335.                                          FailurePoint2a:
  336.                                             ReleasePtr((char*)Filter);
  337.                                             goto FailurePoint2;
  338.                                         }
  339.                                 }
  340.                             if (RightChannel)
  341.                                 {
  342.                                     Filter->Right.FirstOrderLowpass = NewFirstOrderLowpass();
  343.                                     if (Filter->Right.FirstOrderLowpass == NIL)
  344.                                         {
  345.                                             goto FailurePoint2a;
  346.                                         }
  347.                                 }
  348.                             Filter->ApplyFilter = (float (*)(void*,float))&ApplyFirstOrderLowpass;
  349.                             break;
  350.                         case eFilterFirstOrderHighpass:
  351.                             if (LeftChannel)
  352.                                 {
  353.                                     Filter->Left.FirstOrderHighpass = NewFirstOrderHighpass();
  354.                                     if (Filter->Left.FirstOrderHighpass == NIL)
  355.                                         {
  356.                                             goto FailurePoint2a;
  357.                                         }
  358.                                 }
  359.                             if (RightChannel)
  360.                                 {
  361.                                     Filter->Right.FirstOrderHighpass = NewFirstOrderHighpass();
  362.                                     if (Filter->Right.FirstOrderHighpass == NIL)
  363.                                         {
  364.                                             goto FailurePoint2a;
  365.                                         }
  366.                                 }
  367.                             Filter->ApplyFilter = (float (*)(void*,float))&ApplyFirstOrderHighpass;
  368.                             break;
  369.                         case eFilterSecondOrderResonant:
  370.                             if (LeftChannel)
  371.                                 {
  372.                                     Filter->Left.SecondOrderReson = NewSecondOrderReson();
  373.                                     if (Filter->Left.SecondOrderReson == NIL)
  374.                                         {
  375.                                             goto FailurePoint2a;
  376.                                         }
  377.                                 }
  378.                             if (RightChannel)
  379.                                 {
  380.                                     Filter->Right.SecondOrderReson = NewSecondOrderReson();
  381.                                     if (Filter->Right.SecondOrderReson == NIL)
  382.                                         {
  383.                                             goto FailurePoint2a;
  384.                                         }
  385.                                 }
  386.                             Filter->ApplyFilter = (float (*)(void*,float))&ApplySecondOrderReson;
  387.                             break;
  388.                         case eFilterSecondOrderZero:
  389.                             if (LeftChannel)
  390.                                 {
  391.                                     Filter->Left.SecondOrderZero = NewSecondOrderZero();
  392.                                     if (Filter->Left.SecondOrderZero == NIL)
  393.                                         {
  394.                                             goto FailurePoint2a;
  395.                                         }
  396.                                 }
  397.                             if (RightChannel)
  398.                                 {
  399.                                     Filter->Right.SecondOrderZero = NewSecondOrderZero();
  400.                                     if (Filter->Right.SecondOrderZero == NIL)
  401.                                         {
  402.                                             goto FailurePoint2a;
  403.                                         }
  404.                                 }
  405.                             Filter->ApplyFilter = (float (*)(void*,float))&ApplySecondOrderZero;
  406.                             break;
  407.                         case eFilterButterworthLowpass:
  408.                             if (LeftChannel)
  409.                                 {
  410.                                     Filter->Left.ButterworthLowpass = NewButterworthLowpass();
  411.                                     if (Filter->Left.ButterworthLowpass == NIL)
  412.                                         {
  413.                                             goto FailurePoint2a;
  414.                                         }
  415.                                 }
  416.                             if (RightChannel)
  417.                                 {
  418.                                     Filter->Right.ButterworthLowpass = NewButterworthLowpass();
  419.                                     if (Filter->Right.ButterworthLowpass == NIL)
  420.                                         {
  421.                                             goto FailurePoint2a;
  422.                                         }
  423.                                 }
  424.                             Filter->ApplyFilter = (float (*)(void*,float))&ApplyButterworthLowpass;
  425.                             break;
  426.                         case eFilterButterworthHighpass:
  427.                             if (LeftChannel)
  428.                                 {
  429.                                     Filter->Left.ButterworthHighpass = NewButterworthHighpass();
  430.                                     if (Filter->Left.ButterworthHighpass == NIL)
  431.                                         {
  432.                                             goto FailurePoint2a;
  433.                                         }
  434.                                 }
  435.                             if (RightChannel)
  436.                                 {
  437.                                     Filter->Right.ButterworthHighpass = NewButterworthHighpass();
  438.                                     if (Filter->Right.ButterworthHighpass == NIL)
  439.                                         {
  440.                                             goto FailurePoint2a;
  441.                                         }
  442.                                 }
  443.                             Filter->ApplyFilter = (float (*)(void*,float))&ApplyButterworthHighpass;
  444.                             break;
  445.                         case eFilterButterworthBandpass:
  446.                             if (LeftChannel)
  447.                                 {
  448.                                     Filter->Left.ButterworthBandpass = NewButterworthBandpass();
  449.                                     if (Filter->Left.ButterworthBandpass == NIL)
  450.                                         {
  451.                                             goto FailurePoint2a;
  452.                                         }
  453.                                 }
  454.                             if (RightChannel)
  455.                                 {
  456.                                     Filter->Right.ButterworthBandpass = NewButterworthBandpass();
  457.                                     if (Filter->Right.ButterworthBandpass == NIL)
  458.                                         {
  459.                                             goto FailurePoint2a;
  460.                                         }
  461.                                 }
  462.                             Filter->ApplyFilter = (float (*)(void*,float))&ApplyButterworthBandpass;
  463.                             break;
  464.                         case eFilterButterworthBandreject:
  465.                             if (LeftChannel)
  466.                                 {
  467.                                     Filter->Left.ButterworthBandreject = NewButterworthBandreject();
  468.                                     if (Filter->Left.ButterworthBandreject == NIL)
  469.                                         {
  470.                                             goto FailurePoint2a;
  471.                                         }
  472.                                 }
  473.                             if (RightChannel)
  474.                                 {
  475.                                     Filter->Right.ButterworthBandreject = NewButterworthBandreject();
  476.                                     if (Filter->Right.ButterworthBandreject == NIL)
  477.                                         {
  478.                                             goto FailurePoint2a;
  479.                                         }
  480.                                 }
  481.                             Filter->ApplyFilter = (float (*)(void*,float))&ApplyButterworthBandreject;
  482.                             break;
  483.                         case eFilterNull:
  484.                             if (LeftChannel)
  485.                                 {
  486.                                     Filter->Left.NullFilter = NewFilterNull();
  487.                                     if (Filter->Left.NullFilter == NIL)
  488.                                         {
  489.                                             goto FailurePoint2a;
  490.                                         }
  491.                                     Filter->Right.NullFilter = NewFilterNull();
  492.                                     if (Filter->Right.NullFilter == NIL)
  493.                                         {
  494.                                             goto FailurePoint2a;
  495.                                         }
  496.                                 }
  497.                             Filter->ApplyFilter = (float (*)(void*,float))&ApplyFilterNull;
  498.                             break;
  499.                     }
  500.             }
  501.         return Array;
  502.     }
  503.  
  504.  
  505. /* dispose of the filter processor */
  506. void                            DisposeFilterArrayProcessor(FilterArrayRec* Filters)
  507.     {
  508.         CheckPtrExistence(Filters);
  509.         while (Filters->Filters != NIL)
  510.             {
  511.                 FilterRec*            Filter;
  512.  
  513.                 Filter = Filters->Filters;
  514.                 Filters->Filters = Filters->Filters->Next;
  515.                 switch (Filter->FilterType)
  516.                     {
  517.                         default:
  518.                             EXECUTE(PRERR(ForceAbort,"DisposeFilterArrayProcessor:  bad filter type"));
  519.                             break;
  520.                         case eFilterFirstOrderLowpass:
  521.                             if (Filter->Left.FirstOrderLowpass != NIL)
  522.                                 {
  523.                                     DisposeFirstOrderLowpass(Filter->Left.FirstOrderLowpass);
  524.                                 }
  525.                             if (Filter->Right.FirstOrderLowpass != NIL)
  526.                                 {
  527.                                     DisposeFirstOrderLowpass(Filter->Right.FirstOrderLowpass);
  528.                                 }
  529.                             break;
  530.                         case eFilterFirstOrderHighpass:
  531.                             if (Filter->Left.FirstOrderHighpass != NIL)
  532.                                 {
  533.                                     DisposeFirstOrderHighpass(Filter->Left.FirstOrderHighpass);
  534.                                 }
  535.                             if (Filter->Right.FirstOrderHighpass != NIL)
  536.                                 {
  537.                                     DisposeFirstOrderHighpass(Filter->Right.FirstOrderHighpass);
  538.                                 }
  539.                             break;
  540.                         case eFilterSecondOrderResonant:
  541.                             if (Filter->Left.SecondOrderReson != NIL)
  542.                                 {
  543.                                     DisposeSecondOrderReson(Filter->Left.SecondOrderReson);
  544.                                 }
  545.                             if (Filter->Right.SecondOrderReson != NIL)
  546.                                 {
  547.                                     DisposeSecondOrderReson(Filter->Right.SecondOrderReson);
  548.                                 }
  549.                             break;
  550.                         case eFilterSecondOrderZero:
  551.                             if (Filter->Left.SecondOrderZero != NIL)
  552.                                 {
  553.                                     DisposeSecondOrderZero(Filter->Left.SecondOrderZero);
  554.                                 }
  555.                             if (Filter->Right.SecondOrderZero != NIL)
  556.                                 {
  557.                                     DisposeSecondOrderZero(Filter->Right.SecondOrderZero);
  558.                                 }
  559.                             break;
  560.                         case eFilterButterworthLowpass:
  561.                             if (Filter->Left.ButterworthLowpass != NIL)
  562.                                 {
  563.                                     DisposeButterworthLowpass(Filter->Left.ButterworthLowpass);
  564.                                 }
  565.                             if (Filter->Right.ButterworthLowpass != NIL)
  566.                                 {
  567.                                     DisposeButterworthLowpass(Filter->Right.ButterworthLowpass);
  568.                                 }
  569.                             break;
  570.                         case eFilterButterworthHighpass:
  571.                             if (Filter->Left.ButterworthHighpass != NIL)
  572.                                 {
  573.                                     DisposeButterworthHighpass(Filter->Left.ButterworthHighpass);
  574.                                 }
  575.                             if (Filter->Right.ButterworthHighpass != NIL)
  576.                                 {
  577.                                     DisposeButterworthHighpass(Filter->Right.ButterworthHighpass);
  578.                                 }
  579.                             break;
  580.                         case eFilterButterworthBandpass:
  581.                             if (Filter->Left.ButterworthBandpass != NIL)
  582.                                 {
  583.                                     DisposeButterworthBandpass(Filter->Left.ButterworthBandpass);
  584.                                 }
  585.                             if (Filter->Right.ButterworthBandpass != NIL)
  586.                                 {
  587.                                     DisposeButterworthBandpass(Filter->Right.ButterworthBandpass);
  588.                                 }
  589.                             break;
  590.                         case eFilterButterworthBandreject:
  591.                             if (Filter->Left.ButterworthBandreject != NIL)
  592.                                 {
  593.                                     DisposeButterworthBandreject(Filter->Left.ButterworthBandreject);
  594.                                 }
  595.                             if (Filter->Right.ButterworthBandreject != NIL)
  596.                                 {
  597.                                     DisposeButterworthBandreject(Filter->Right.ButterworthBandreject);
  598.                                 }
  599.                             break;
  600.                         case eFilterNull:
  601.                             if (Filter->Left.NullFilter != NIL)
  602.                                 {
  603.                                     DisposeFilterNull(Filter->Left.NullFilter);
  604.                                 }
  605.                             if (Filter->Right.NullFilter != NIL)
  606.                                 {
  607.                                     DisposeFilterNull(Filter->Right.NullFilter);
  608.                                 }
  609.                             break;
  610.                     }
  611.                 Filter->Next = FilterFreeList;
  612.                 FilterFreeList = Filter;
  613.             }
  614.         Filters->Next = FilterArrayFreeList;
  615.         FilterArrayFreeList = Filters;
  616.     }
  617.  
  618.  
  619. /* update filter state with accent information */
  620. void                            UpdateFilterArrayState(FilterArrayRec* Filters, float Accent1,
  621.                                         float Accent2, float Accent3, float Accent4)
  622.     {
  623.         FilterRec*            Scan;
  624.  
  625.         CheckPtrExistence(Filters);
  626.         Scan = Filters->Filters;
  627.         while (Scan != NIL)
  628.             {
  629.                 float                        Cutoff;
  630.                 float                        Bandwidth;
  631.  
  632.                 Scan->CurrentMultiplier = Scan->OutputMultiplier
  633.                     + Scan->OutputMultiplierAccent1 * Accent1
  634.                     + Scan->OutputMultiplierAccent2 * Accent2
  635.                     + Scan->OutputMultiplierAccent3 * Accent3
  636.                     + Scan->OutputMultiplierAccent4 * Accent4;
  637.                 Cutoff = Scan->Cutoff + Scan->CutoffAccent1 * Accent1
  638.                     + Scan->CutoffAccent2 * Accent2 + Scan->CutoffAccent3 * Accent3
  639.                     + Scan->CutoffAccent4 * Accent4;
  640.                 switch (Scan->FilterType)
  641.                     {
  642.                         default:
  643.                             EXECUTE(PRERR(ForceAbort,"UpdateFilterArrayState:  bad filter type"));
  644.                             break;
  645.                         case eFilterFirstOrderLowpass:
  646.                             if (Scan->Left.FirstOrderLowpass != NIL)
  647.                                 {
  648.                                     SetFirstOrderLowpassCoefficients(Scan->Left.FirstOrderLowpass,
  649.                                         Cutoff,Filters->SamplingRate);
  650.                                 }
  651.                             if (Scan->Right.FirstOrderLowpass != NIL)
  652.                                 {
  653.                                     SetFirstOrderLowpassCoefficients(Scan->Right.FirstOrderLowpass,
  654.                                         Cutoff,Filters->SamplingRate);
  655.                                 }
  656.                             ERROR(Scan->FilterScaling != eFilterDefaultScaling,PRERR(ForceAbort,
  657.                                 "UpdateFilterArrayState:  bad scaling type"));
  658.                             break;
  659.                         case eFilterFirstOrderHighpass:
  660.                             if (Scan->Left.FirstOrderHighpass != NIL)
  661.                                 {
  662.                                     SetFirstOrderHighpassCoefficients(Scan->Left.FirstOrderHighpass,
  663.                                         Cutoff,Filters->SamplingRate);
  664.                                 }
  665.                             if (Scan->Right.FirstOrderHighpass != NIL)
  666.                                 {
  667.                                     SetFirstOrderHighpassCoefficients(Scan->Right.FirstOrderHighpass,
  668.                                         Cutoff,Filters->SamplingRate);
  669.                                 }
  670.                             ERROR(Scan->FilterScaling != eFilterDefaultScaling,PRERR(ForceAbort,
  671.                                 "UpdateFilterArrayState:  bad scaling type"));
  672.                             break;
  673.                         case eFilterSecondOrderResonant:
  674.                             Bandwidth = Scan->Bandwidth + Scan->BandwidthAccent1 * Accent1
  675.                                 + Scan->BandwidthAccent2 * Accent2 + Scan->BandwidthAccent3 * Accent3
  676.                                 + Scan->BandwidthAccent4 * Accent4;
  677.                             if (Scan->Left.SecondOrderReson != NIL)
  678.                                 {
  679.                                     SetSecondOrderResonCoefficients(Scan->Left.SecondOrderReson,
  680.                                         Cutoff,Bandwidth,Scan->FilterScaling,Filters->SamplingRate);
  681.                                 }
  682.                             if (Scan->Right.SecondOrderReson != NIL)
  683.                                 {
  684.                                     SetSecondOrderResonCoefficients(Scan->Right.SecondOrderReson,
  685.                                         Cutoff,Bandwidth,Scan->FilterScaling,Filters->SamplingRate);
  686.                                 }
  687.                             break;
  688.                         case eFilterSecondOrderZero:
  689.                             Bandwidth = Scan->Bandwidth + Scan->BandwidthAccent1 * Accent1
  690.                                 + Scan->BandwidthAccent2 * Accent2 + Scan->BandwidthAccent3 * Accent3
  691.                                 + Scan->BandwidthAccent4 * Accent4;
  692.                             if (Scan->Left.SecondOrderZero != NIL)
  693.                                 {
  694.                                     SetSecondOrderZeroCoefficients(Scan->Left.SecondOrderZero,
  695.                                         Cutoff,Bandwidth,Scan->FilterScaling,Filters->SamplingRate);
  696.                                 }
  697.                             if (Scan->Right.SecondOrderZero != NIL)
  698.                                 {
  699.                                     SetSecondOrderZeroCoefficients(Scan->Right.SecondOrderZero,
  700.                                         Cutoff,Bandwidth,Scan->FilterScaling,Filters->SamplingRate);
  701.                                 }
  702.                             break;
  703.                         case eFilterButterworthLowpass:
  704.                             if (Scan->Left.ButterworthLowpass != NIL)
  705.                                 {
  706.                                     SetButterworthLowpassCoefficients(Scan->Left.ButterworthLowpass,
  707.                                         Cutoff,Filters->SamplingRate);
  708.                                 }
  709.                             if (Scan->Right.ButterworthLowpass != NIL)
  710.                                 {
  711.                                     SetButterworthLowpassCoefficients(Scan->Right.ButterworthLowpass,
  712.                                         Cutoff,Filters->SamplingRate);
  713.                                 }
  714.                             ERROR(Scan->FilterScaling != eFilterDefaultScaling,PRERR(ForceAbort,
  715.                                 "UpdateFilterArrayState:  bad scaling type"));
  716.                             break;
  717.                         case eFilterButterworthHighpass:
  718.                             if (Scan->Left.ButterworthHighpass != NIL)
  719.                                 {
  720.                                     SetButterworthHighpassCoefficients(Scan->Left.ButterworthHighpass,
  721.                                         Cutoff,Filters->SamplingRate);
  722.                                 }
  723.                             if (Scan->Right.ButterworthHighpass != NIL)
  724.                                 {
  725.                                     SetButterworthHighpassCoefficients(Scan->Right.ButterworthHighpass,
  726.                                         Cutoff,Filters->SamplingRate);
  727.                                 }
  728.                             ERROR(Scan->FilterScaling != eFilterDefaultScaling,PRERR(ForceAbort,
  729.                                 "UpdateFilterArrayState:  bad scaling type"));
  730.                             break;
  731.                         case eFilterButterworthBandpass:
  732.                             Bandwidth = Scan->Bandwidth + Scan->BandwidthAccent1 * Accent1
  733.                                 + Scan->BandwidthAccent2 * Accent2 + Scan->BandwidthAccent3 * Accent3
  734.                                 + Scan->BandwidthAccent4 * Accent4;
  735.                             if (Scan->Left.ButterworthBandpass != NIL)
  736.                                 {
  737.                                     SetButterworthBandpassCoefficients(Scan->Left.ButterworthBandpass,
  738.                                         Cutoff,Bandwidth,Filters->SamplingRate);
  739.                                 }
  740.                             if (Scan->Right.ButterworthBandpass != NIL)
  741.                                 {
  742.                                     SetButterworthBandpassCoefficients(Scan->Right.ButterworthBandpass,
  743.                                         Cutoff,Bandwidth,Filters->SamplingRate);
  744.                                 }
  745.                             ERROR(Scan->FilterScaling != eFilterDefaultScaling,PRERR(ForceAbort,
  746.                                 "UpdateFilterArrayState:  bad scaling type"));
  747.                             break;
  748.                         case eFilterButterworthBandreject:
  749.                             Bandwidth = Scan->Bandwidth + Scan->BandwidthAccent1 * Accent1
  750.                                 + Scan->BandwidthAccent2 * Accent2 + Scan->BandwidthAccent3 * Accent3
  751.                                 + Scan->BandwidthAccent4 * Accent4;
  752.                             if (Scan->Left.ButterworthBandreject != NIL)
  753.                                 {
  754.                                     SetButterworthBandrejectCoefficients(Scan->Left.ButterworthBandreject,
  755.                                         Cutoff,Bandwidth,Filters->SamplingRate);
  756.                                 }
  757.                             if (Scan->Right.ButterworthBandreject != NIL)
  758.                                 {
  759.                                     SetButterworthBandrejectCoefficients(Scan->Right.ButterworthBandreject,
  760.                                         Cutoff,Bandwidth,Filters->SamplingRate);
  761.                                 }
  762.                             ERROR(Scan->FilterScaling != eFilterDefaultScaling,PRERR(ForceAbort,
  763.                                 "UpdateFilterArrayState:  bad scaling type"));
  764.                             break;
  765.                         case eFilterNull:
  766.                             ERROR(Scan->FilterScaling != eFilterDefaultScaling,PRERR(ForceAbort,
  767.                                 "UpdateFilterArrayState:  bad scaling type"));
  768.                             break;
  769.                     }
  770.                 Scan = Scan->Next;
  771.             }
  772.     }
  773.  
  774.  
  775. /* apply filter processing to some stuff */
  776. void                            ApplyFilterArray(largefixedsigned* Data, long NumFrames,
  777.                                         FilterArrayRec* Filters)
  778.     {
  779.         long                        Scan;
  780.  
  781.         CheckPtrExistence(Data);
  782.         CheckPtrExistence(Filters);
  783.         if (Filters->StereoFlag)
  784.             {
  785.                 for (Scan = 0; Scan < NumFrames; Scan += 1)
  786.                     {
  787.                         float                        LeftInput;
  788.                         float                        LeftOutput;
  789.                         float                        RightInput;
  790.                         float                        RightOutput;
  791.                         FilterRec*            Filter;
  792.         
  793.                         PRNGCHK(Data,&(Data[2 * Scan]),sizeof(Data[2 * Scan]));
  794.                         PRNGCHK(Data,&(Data[2 * Scan + 1]),sizeof(Data[2 * Scan + 1]));
  795.                         LeftInput = largefixed2single(Data[2 * Scan]);
  796.                         RightInput = largefixed2single(Data[2 * Scan + 1]);
  797.                         LeftOutput = 0;
  798.                         RightOutput = 0;
  799.                         Filter = Filters->Filters;
  800.                         while (Filter != NIL)
  801.                             {
  802.                                 if (Filter->Left.GenericRef != NIL)
  803.                                     {
  804.                                         LeftOutput += Filter->CurrentMultiplier
  805.                                             * (*Filter->ApplyFilter)(Filter->Left.GenericRef,LeftInput);
  806.                                     }
  807.                                 if (Filter->Right.GenericRef != NIL)
  808.                                     {
  809.                                         RightOutput += Filter->CurrentMultiplier
  810.                                             * (*Filter->ApplyFilter)(Filter->Right.GenericRef,RightInput);
  811.                                     }
  812.                                 Filter = Filter->Next;
  813.                             }
  814.                         Data[2 * Scan] = double2largefixed(LeftOutput);
  815.                         Data[2 * Scan + 1] = double2largefixed(RightOutput);
  816.                     }
  817.             }
  818.          else
  819.             {
  820.                 for (Scan = 0; Scan < NumFrames; Scan += 1)
  821.                     {
  822.                         float                        LeftInput;
  823.                         float                        LeftOutput;
  824.                         float                        RightInput;
  825.                         float                        RightOutput;
  826.                         FilterRec*            Filter;
  827.         
  828.                         PRNGCHK(Data,&(Data[Scan]),sizeof(Data[Scan]));
  829.                         LeftInput = largefixed2single(Data[Scan]);
  830.                         RightInput = largefixed2single(Data[Scan]);
  831.                         LeftOutput = 0;
  832.                         RightOutput = 0;
  833.                         Filter = Filters->Filters;
  834.                         while (Filter != NIL)
  835.                             {
  836.                                 if (Filter->Left.GenericRef != NIL)
  837.                                     {
  838.                                         LeftOutput += Filter->CurrentMultiplier
  839.                                             * (*Filter->ApplyFilter)(Filter->Left.GenericRef,LeftInput);
  840.                                     }
  841.                                 if (Filter->Right.GenericRef != NIL)
  842.                                     {
  843.                                         RightOutput += Filter->CurrentMultiplier
  844.                                             * (*Filter->ApplyFilter)(Filter->Right.GenericRef,RightInput);
  845.                                     }
  846.                                 Filter = Filter->Next;
  847.                             }
  848.                         Data[Scan] = double2largefixed((LeftOutput + RightOutput) / 2);
  849.                     }
  850.             }
  851.     }
  852.